package org.dant.ant.extension.net.soap;
 
import java.util.*;
import java.net.*;

import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;

import org.dant.ant.extension.net.RemoteHelper;
import org.dant.ant.extension.tasks.internal.RemoteCommand;
import org.dant.ant.extension.tasks.internal.RemoteResponse;
import org.dant.ant.extension.tasks.internal.Endpoint;
import org.dant.ant.extension.net.NetConstants;

public class SOAPServiceHelper implements RemoteHelper {
 
  public String getProtocol() {
    return NetConstants.SOAP_SERVICE_PROTOCOL;
  }
 
  public String getPath() {
    return NetConstants.SOAP_SERVICE_PATH;
  }
 
  public RemoteResponse invoke(Endpoint destHost, RemoteCommand rcmd) throws Exception {

    SOAPMappingRegistry smr = new SOAPMappingRegistry();
    GenericBeanSerializer beanSer = new GenericBeanSerializer();
    StringBufferSerializer sbSer = new StringBufferSerializer();
    
    smr.mapTypes(Constants.NS_URI_SOAP_ENC,
                 new QName("urn:dant-soap-service", "remoteCommand"),
                 RemoteCommand.class, beanSer, beanSer);
    smr.mapTypes(Constants.NS_URI_SOAP_ENC,
                 new QName("urn:dant-soap-service", "remoteResponse"),
                 RemoteResponse.class, beanSer, beanSer);
    smr.mapTypes(Constants.NS_URI_SOAP_ENC,
                 new QName("urn:dant-soap-service", "stringBuffer"),
                 StringBuffer.class, sbSer, sbSer);
    
    Call call = new Call();
    call.setSOAPMappingRegistry(smr);
    call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
    call.setTargetObjectURI(NetConstants.SOAP_SERVICE_TARGET_URI);
    call.setMethodName("remoteCall");
    
    Vector params = new Vector();
    params.add(new Parameter("rCmd", RemoteCommand.class, rcmd, null));
     
    call.setParams(params);
    Response resp = call.invoke(new URL(destHost.getFullURL()), new String(""));

    if (!resp.generatedFault()) {
      Parameter ret = resp.getReturnValue();
      Object value = ret.getValue();
      return (RemoteResponse) value;
    } else {
      Fault fault = resp.getFault();
      System.err.println("Generated fault: " + fault);
      RemoteResponse rr = new RemoteResponse();
      rr.setSuccess(false);
      rr.appendResult(fault);
      return rr;
    }
  }
}
